// import com.alibaba.druid.sql.ast.SQLDataType;
// import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
// import com.alibaba.druid.sql.ast.SQLObject;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

// import java.math.BigDecimal;
// import java.util.Collections;
// import java.util.List;

#include "SQLDecimalExpr.h"
#include "../SQLDataTypeImpl.h"
#include "../../visitor/SQLASTVisitor.h"
#include "../../../utils/doubleEqual.h"

SQLDataType_ptr SQLDecimalExpr::DATA_TYPE = SQLDataTypeImpl_ptr(new SQLDataTypeImpl(make_string_ptr("DECIMAL")));

SQLDecimalExpr::SQLDecimalExpr()
{
}

SQLDecimalExpr::SQLDecimalExpr(double value)
    : SQLNumericLiteralExpr()
{

  this->value = value;
}

SQLDecimalExpr::SQLDecimalExpr(string_ptr value)
    : SQLNumericLiteralExpr()
{
  this->value = atof(value->c_str());
  this->literal = value;
}

string_ptr SQLDecimalExpr::getLiteral()
{
  return literal;
}

SQLObject_ptr SQLDecimalExpr::clone()
{
  // return new SQLDecimalExpr(value);

  SQLObject_ptr clone_tmp = std::shared_ptr<SQLDecimalExpr>(new SQLDecimalExpr(value));
  std::shared_ptr<SQLDecimalExpr> clone_res = std::dynamic_pointer_cast<SQLDecimalExpr>(clone_tmp);
  return clone_res;
}

//@Override
SQLObject_list_ptr SQLDecimalExpr::getChildren()
{
  return SQLObject_list_ptr();
}

//@Override
double SQLDecimalExpr::getNumber()
{
  return value;
}

double SQLDecimalExpr::getValue()
{
  return value;
}

void SQLDecimalExpr::setValue(double value)
{
  this->value = value;
}

void SQLDecimalExpr::accept0(SQLASTVisitor_ptr visitor)
{
  visitor->visit(SharedObject(SQLDecimalExpr));

  visitor->endVisit(SharedObject(SQLDecimalExpr));
}

//@Override
int SQLDecimalExpr::hashCode()
{
  int prime = 31;
  int result = 1;
  // result = prime * result + ((value == null) ? 0 : value.hashCode());
  result = prime * result + (int)value;
  return result;
}

//@Override
bool SQLDecimalExpr::equals(Object_ptr obj)
{
  if (this == obj.get())
  {
    return true;
  }
  if (obj == nullptr)
  {
    return false;
  }
  if (getClass() != obj->getClass())
  {
    return false;
  }
  std::shared_ptr<SQLDecimalExpr> other = std::dynamic_pointer_cast<SQLDecimalExpr>(obj);
  // if (value == null) {
  //     if (other.value != null) {
  //         return BOOL::FALSE;
  //     }
  // } else
  if (!doubleEqual::AreEqual(value, other->value))
  {
    return false;
  }
  return true;
}

//@Override
void SQLDecimalExpr::setNumber(double number)
{
  // if (number == null) {
  //     this->setValue(null);
  //     return;
  // }

  this->setValue((/*(BigDecimal)*/ number));
}

//@Override
int SQLDecimalExpr::compareTo(std::shared_ptr<SQLDecimalExpr> o)
{
  // return value.compareTo(o.value);
  if (doubleEqual::AreEqual(value, o->value))
  {
    return 0;
  }

  if (value > o->value)
  {
    return 1;
  }

  return -1;
}
